#include "TextureLoader.h"
#include "Texture.h"
#include <SOIL2.h>
#include "Log.h"

namespace SCION_RENDERING
{
  bool TextureLoader::LoadTexture(const std::string &filepath, GLuint &id, int &width, int &height, bool blended)
  {
    int channels = 0;
    unsigned char *image = SOIL_load_image(filepath.c_str(),
                                           &width,
                                           &height,
                                           &channels,
                                           SOIL_LOAD_AUTO);
    if (!image)
    {
      SCION_INFO("SOIL2 failed to load image [" + filepath + "]" + " -- " + SOIL_last_result());
      return false;
    }
    GLint format = GL_RGBA;
    switch (channels)
    {
    case 3:
      format = GL_RGB;
      break;
    case 4:
      format = GL_RGBA;
      break;
    default:
      break;
    }
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    if (!blended)
    {
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    }
    else
    {
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    }
    glTexImage2D(
        GL_TEXTURE_2D,
        0,
        format,
        width,
        height,
        0,
        format,
        GL_UNSIGNED_BYTE,
        image);
    // ɾ��soil�е�image ����
    SOIL_free_image_data(image);
    return true;
  }

  std::shared_ptr<Texture> TextureLoader::Creat(Texture::TextureType type, const std::string &texturePath)
  {
    GLuint id;
    int width, height;
    glGenTextures(1, &id);
    glBindTexture(GL_TEXTURE_2D, id);

    switch (type)
    {
    case Texture::TextureType::PIXEL:
      LoadTexture(texturePath, id, width, height, false);
      break;
    case Texture::TextureType::BLENDED:
      LoadTexture(texturePath, id, width, height, true);
      break;
    default:
      assert(false && "The current type is not defined,Please use a defined textrue type!");
      return nullptr;
    }
    return std::make_shared<Texture>(id, width, height, type, texturePath);
  }
}